#include "io.h"

IO::IO()
: _data( 0 )
, _width( 0 )
, _height( 0 )
{
}

IO::~IO()
{
}

void IO::Init( const std::string& title, uint width, uint height )
{
    _data   = new DataArray( boost::extents[ width ][ height ][ LAYERS ] );
    _bg     = new   BGArray( boost::extents[ width ][ height ][ LAYERS ] );
    _width  = width;
    _height = height;
    InitInternal();
    SetTitle( title );
}

void IO::Destroy()
{
    DestroyInternal();
    delete _data;
    delete _bg;
}

void IO::ShowCursor( uint x, uint y )
{
    if ( x >= _width || y >= _height )
        return;
    _coordSet.clear();
    _coordSet.insert( Coord( x, y ) );
}

void IO::ShowCursor( const CoordSet& set )
{
    _coordSet = set;
}

void IO::HideCursor()
{
    _coordSet.clear();
}

void IO::Clear( uint layer )
{
    for ( uint x = 0; x < _width; x++ ) {
        for ( uint y = 0; y < _height; y++ ) {
            ( *_data )[ x ][ y ][ layer ].clear();
            ( *_bg )[ x ][ y ][ layer ] = Colour( 0, 0, 0 );
        }
    }
}

void IO::Clear()
{
    for ( uint k = 0; k < LAYERS; k++ )
        Clear( k );
}

void IO::Draw( uchar ch, const Colour& c, uint x, uint y, uint layer )
{
    if ( x >= _width || y >= _height || layer >= LAYERS )
        return;

    ( *_data )[ x ][ y ][ layer ].clear();
    ( *_data )[ x ][ y ][ layer ].push_back( Sym( ch, c ) );
}

void IO::Draw( const SymList& list, uint x, uint y, uint layer )
{
    if ( x >= _width || y >= _height || layer >= LAYERS )
        return;

    ( *_data )[ x ][ y ][ layer ] = list;
}

void IO::Draw( const ustring& text, const Colour& c, uint x, uint y, uint layer )
{
    if ( x >= _width || y >= _height || layer >= LAYERS )
        return;

    uint row = 0;
    uint col = 0;
    for ( uint i = 0; i < text.length(); i++ ) {
        if ( text[ i ] == '\n' ) {
            row++;
            col = 0;
            continue;
        }

        if ( x + col >= _width ) {
            row++;
            col = 0;
        }

        if ( y + row >= _height )
            break;
        
        Draw( text[ i ], c, x + col, y + row, layer );
        col++;
    }
}

void IO::Draw( const std::string& text, const Colour& c, uint x, uint y, uint layer )
{
    Draw( ustring( text ), c, x, y, layer );
}

void IO::Draw( const Colour& c, uint x, uint y, uint layer )
{
    if ( x >= _width || y >= _height || layer >= LAYERS )
        return;

    ( *_bg )[ x ][ y ][ layer ] = c;
}
